/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * BreakpointNestedGroupsDialog.java
 *
 * Created on Jan 20, 2010, 10:52:27 PM
 */

package org.netbeans.modules.debugger.ui.models;

import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;

import org.netbeans.modules.debugger.ui.models.BreakpointGroup.Group;
import org.openide.util.NbBundle;

/**
 *
 * @author Martin Entlicher
 */
public class BreakpointNestedGroupsDialog extends javax.swing.JPanel {

    /** Creates new form BreakpointNestedGroupsDialog */
    public BreakpointNestedGroupsDialog() {
        initComponents();
        setAvailableGroups();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                availableGroupsList.setSelectedIndex(0);
                displayedGroupsList.setSelectedIndex(0);
            }
        });
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        availableGroupsPanel = new javax.swing.JPanel();
        availableGroupsLabel = new javax.swing.JLabel();
        availableGroupsScrollPane = new javax.swing.JScrollPane();
        availableGroupsList = new javax.swing.JList();
        buttonPanel = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        moveUpButton = new javax.swing.JButton();
        moveDownButton = new javax.swing.JButton();
        displayedGroupsPanel = new javax.swing.JPanel();
        displayedGroupsLabel = new javax.swing.JLabel();
        displayedGroupsScrollPane = new javax.swing.JScrollPane();
        displayedGroupsList = new javax.swing.JList();

        setLayout(new java.awt.GridBagLayout());

        availableGroupsPanel.setLayout(new java.awt.GridBagLayout());

        availableGroupsLabel.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.availableGroupsLabel.text")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        availableGroupsPanel.add(availableGroupsLabel, gridBagConstraints);

        availableGroupsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                availableGroupsListValueChanged(evt);
            }
        });
        availableGroupsScrollPane.setViewportView(availableGroupsList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0);
        availableGroupsPanel.add(availableGroupsScrollPane, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 12, 12);
        add(availableGroupsPanel, gridBagConstraints);

        buttonPanel.setLayout(new java.awt.GridBagLayout());

        addButton.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.addButton.text")); // NOI18N
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        buttonPanel.add(addButton, gridBagConstraints);

        removeButton.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.removeButton.text")); // NOI18N
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        buttonPanel.add(removeButton, gridBagConstraints);

        moveUpButton.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.moveUpButton.text")); // NOI18N
        moveUpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveUpButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        buttonPanel.add(moveUpButton, gridBagConstraints);

        moveDownButton.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.moveDownButton.text")); // NOI18N
        moveDownButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveDownButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        buttonPanel.add(moveDownButton, gridBagConstraints);

        add(buttonPanel, new java.awt.GridBagConstraints());

        displayedGroupsPanel.setLayout(new java.awt.GridBagLayout());

        displayedGroupsLabel.setText(org.openide.util.NbBundle.getMessage(BreakpointNestedGroupsDialog.class, "BreakpointNestedGroupsDialog.displayedGroupsLabel.text")); // NOI18N
        displayedGroupsPanel.add(displayedGroupsLabel, new java.awt.GridBagConstraints());

        displayedGroupsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                displayedGroupsListValueChanged(evt);
            }
        });
        displayedGroupsScrollPane.setViewportView(displayedGroupsList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0);
        displayedGroupsPanel.add(displayedGroupsScrollPane, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 12, 12);
        add(displayedGroupsPanel, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        int[] indexes = availableGroupsList.getSelectedIndices();
        DefaultListModel availableModel = (DefaultListModel) availableGroupsList.getModel();
        DefaultListModel displayedModel = (DefaultListModel) displayedGroupsList.getModel();
        int at = displayedModel.getSize();
        for (int i = indexes.length - 1; i >= 0; i--) {
            Object element = availableModel.remove(indexes[i]);
            displayedModel.add(at, element);
        }
    }//GEN-LAST:event_addButtonActionPerformed

    private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
        int[] indexes = displayedGroupsList.getSelectedIndices();
        DefaultListModel availableModel = (DefaultListModel) availableGroupsList.getModel();
        DefaultListModel displayedModel = (DefaultListModel) displayedGroupsList.getModel();
        int at = availableModel.getSize();
        for (int i = indexes.length - 1; i >= 0; i--) {
            Object element = displayedModel.remove(indexes[i]);
            availableModel.add(at, element);
        }
    }//GEN-LAST:event_removeButtonActionPerformed

    private void moveUpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveUpButtonActionPerformed
        int[] indexes = displayedGroupsList.getSelectedIndices();
        DefaultListModel displayedModel = (DefaultListModel) displayedGroupsList.getModel();
        for (int index : indexes) {
            Object down = displayedModel.get(index - 1);
            Object up = displayedModel.get(index);
            displayedModel.set(index, down);
            displayedModel.set(index - 1, up);
        }
        for (int i = 0; i < indexes.length; i++) {
            indexes[i]--;
        }
        displayedGroupsList.setSelectedIndices(indexes);
    }//GEN-LAST:event_moveUpButtonActionPerformed

    private void moveDownButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveDownButtonActionPerformed
        int[] indexes = displayedGroupsList.getSelectedIndices();
        DefaultListModel displayedModel = (DefaultListModel) displayedGroupsList.getModel();
        for (int index : indexes) {
            Object down = displayedModel.get(index);
            Object up = displayedModel.get(index + 1);
            displayedModel.set(index + 1, down);
            displayedModel.set(index, up);
        }
        for (int i = 0; i < indexes.length; i++) {
            indexes[i]++;
        }
        displayedGroupsList.setSelectedIndices(indexes);
    }//GEN-LAST:event_moveDownButtonActionPerformed

    private void availableGroupsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_availableGroupsListValueChanged
        Object selected = availableGroupsList.getSelectedValue();
        addButton.setEnabled(selected != null);
    }//GEN-LAST:event_availableGroupsListValueChanged

    private void displayedGroupsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_displayedGroupsListValueChanged
        int[] selected = displayedGroupsList.getSelectedIndices();
        removeButton.setEnabled(selected.length > 0);
        moveUpButton.setEnabled(selected.length > 0 && selected[0] > 0);
        moveDownButton.setEnabled(selected.length > 0 && selected[selected.length - 1] < (displayedGroupsList.getModel().getSize() - 1));
    }//GEN-LAST:event_displayedGroupsListValueChanged


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JLabel availableGroupsLabel;
    private javax.swing.JList availableGroupsList;
    private javax.swing.JPanel availableGroupsPanel;
    private javax.swing.JScrollPane availableGroupsScrollPane;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JLabel displayedGroupsLabel;
    private javax.swing.JList displayedGroupsList;
    private javax.swing.JPanel displayedGroupsPanel;
    private javax.swing.JScrollPane displayedGroupsScrollPane;
    private javax.swing.JButton moveDownButton;
    private javax.swing.JButton moveUpButton;
    private javax.swing.JButton removeButton;
    // End of variables declaration//GEN-END:variables

    private void setAvailableGroups() {
        DefaultListModel model = new DefaultListModel();
        model.addElement(new GroupElement(Group.CUSTOM));
        model.addElement(new GroupElement(Group.LANGUAGE));
        model.addElement(new GroupElement(Group.TYPE));
        model.addElement(new GroupElement(Group.PROJECT));
        model.addElement(new GroupElement(Group.FILE));
        model.addElement(new GroupElement(Group.ENGINE));
        availableGroupsList.setModel(model);
    }

    void setDisplayedGroups(String[] groupNames) {
        DefaultListModel availableModel = (DefaultListModel) availableGroupsList.getModel();
        DefaultListModel model = new DefaultListModel();
        for (String groupName : groupNames) {
            Group g;
            try {
                g = Group.valueOf(groupName);
            } catch (IllegalArgumentException iaex) {
                continue;
            }
            GroupElement ge = new GroupElement(g);
            model.addElement(ge);
            availableModel.removeElement(ge);
        }
        displayedGroupsList.setModel(model);
    }

    String[] getDisplayedGroups() {
        ListModel model = displayedGroupsList.getModel();
        int n = model.getSize();
        String[] groupNames = new String[n];
        for (int i = 0; i < n; i++) {
            GroupElement ge = (GroupElement) model.getElementAt(i);
            groupNames[i] = ge.getGroup().name();
        }
        return groupNames;
    }

    private static final class GroupElement {

        private Group group;

        public GroupElement(Group group) {
            this.group = group;
        }

        Group getGroup() {
            return group;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof GroupElement)) return false;
            return group.equals(((GroupElement) obj).group);
        }

        @Override
        public int hashCode() {
            return group.hashCode();
        }

        @Override
        public String toString() {
            String name = "LBL_"+group.name()+"Group"; // NOI18N
            name = NbBundle.getMessage (BreakpointsViewButtons.class, name);
            return name;
        }

    }

}
